package com.lion.common.modules.uaa.service.impl;

import com.lion.common.base.constants.HttpConstants;
import com.lion.common.base.exceptions.CommonException;
import com.lion.common.modules.uaa.common.ErrorMessages;
import com.lion.common.modules.uaa.common.assistants.JwtAssist;
import com.lion.common.modules.uaa.domain.entity.UaaAccountEntity;
import com.lion.common.modules.uaa.service.assistants.EmailAssistantImpl;
import com.lion.common.modules.uaa.service.assistants.LoginAssistantImpl;
import com.lion.common.modules.uaa.service.assistants.SmsAssistantImpl;
import com.lion.common.modules.uaa.service.assistants.VerifyCodeAssistantImpl;
import com.lion.common.modules.uaa.service.def.AccountService;
import com.lion.common.modules.uaa.service.def.AuthAccountService;
import com.lion.common.modules.uaa.utils.CaptchaGenerator;
import com.lion.common.modules.uaa.utils.VerifyUtil;
import com.lion.common.modules.uaa.web.models.results.LoginResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;

/**
 * @author Chris Chan
 * Create On 2025/7/29 下午7:54
 * Use for:
 * Explain:
 */
@Slf4j
@Service
public class AuthAccountServiceImpl implements AuthAccountService, ErrorMessages {

    private final JwtAssist jwtAssist;
    private final VerifyCodeAssistantImpl verifyCodeAssistant;
    private final SmsAssistantImpl smsAssistant;
    private final EmailAssistantImpl emailAssistant;
    private final AccountService<UaaAccountEntity> accountService;
    private final LoginAssistantImpl loginAssistant;

    @Autowired
    public AuthAccountServiceImpl(JwtAssist jwtAssist,
                                  @Autowired VerifyCodeAssistantImpl verifyCodeAssistant,
                                  @Autowired SmsAssistantImpl smsAssistant,
                                  @Autowired EmailAssistantImpl emailAssistant,
                                  @Autowired AccountService accountService,
                                  @Autowired LoginAssistantImpl loginAssistant) {
        this.jwtAssist = jwtAssist;
        this.verifyCodeAssistant = verifyCodeAssistant;
        this.smsAssistant = smsAssistant;
        this.emailAssistant = emailAssistant;
        this.accountService = accountService;
        this.loginAssistant = loginAssistant;
    }

    @Override
    public String getGraphVerifyCode() {
        try {
            // 获得默认配置
            CaptchaGenerator.CaptchaConfig config = new CaptchaGenerator.CaptchaConfig.Builder().build();
            // 生成随机验证码
            String captchaText = CaptchaGenerator.generateRandomText(config.getCodeCount());
            log.info("验证码: {}", captchaText);
            // 生成图片Base64字符串
            return CaptchaGenerator.generateCaptchaBase64(config, captchaText);
        } catch (IOException e) {
            throw CommonException.of("获取验证码失败");
        }
    }

    @Override
    public boolean sendMobileVerifyCode(String cellphone) {
        // 生成随机验证码
        String code = verifyCodeAssistant.buildRandomCode(6);
        // 发送验证码
        return smsAssistant.sendMobileVerifyCode(cellphone, code);
    }

    @Override
    public boolean sendEmailVerifyCode(String email) {
        // 生成随机验证码
        String code = verifyCodeAssistant.buildRandomCode(6);
        // 发送验证码
        return emailAssistant.sendEmailVerifyCode(email, code);
    }

    @Override
    public boolean registerByUsernamePassword(String username, String password, String confirmPassword, String verificationCode) {
        // 校验验证码
        boolean verify = verifyCodeAssistant.checkGraphVerifyCode(verificationCode);
        if (!verify) {
            throw CommonException.of(VERIFY_CODE_ERROR);
        }
        // 校验密码
        VerifyUtil.verifyPasswordAndConfirmPassword(password, confirmPassword);
        // 检查用户名是否已经存在
        UaaAccountEntity account = accountService.findAccountByUsername(username);
        if (account != null) {
            throw CommonException.of(USERNAME_EXISTS);
        }
        // 注册
        accountService.addAccountWithUsernamePassword(username, password);
        return true;
    }

    @Override
    public boolean registerByMobileVerifyCode(String cellphone, String verifyCode) {
        // 校验验证码
        boolean verify = verifyCodeAssistant.checkSmsVerifyCode(cellphone, verifyCode);
        if (!verify) {
            throw CommonException.of(VERIFY_CODE_ERROR);
        }
        // 注册
        accountService.addAccountWithMobileVerifyCode(cellphone);
        return true;
    }

    @Override
    public boolean registerByEmailVerifyCode(String email, String verifyCode) {
        boolean verify = verifyCodeAssistant.checkEmailVerifyCode(email, verifyCode);
        if (!verify) {
            throw CommonException.of(VERIFY_CODE_ERROR);
        }
        // 注册
        accountService.addAccountWithEmailVerifyCode(email);
        return true;
    }

    @Override
    public LoginResult loginByMobileVerifyCode(String mobile, String verifyCode) {
        // 校验验证码
        boolean verify = verifyCodeAssistant.checkSmsVerifyCode(mobile, verifyCode);
        if (!verify) {
            throw CommonException.of(VERIFY_CODE_ERROR);
        }
        // 查找账号
        UaaAccountEntity account = accountService.findAccountByMobile(mobile);
        if (account == null) {
            throw CommonException.of(USER_NOT_FOUND);
        }
        // 取出账号
        String username = account.getUsername();
        Long userCode = account.getCode();
        // 登录
        return loginAssistant.buildLoginResult(userCode, username);
    }

    @Override
    public LoginResult loginByEmailVerifyCode(String email, String verifyCode) {
        // 校验验证码
        boolean verify = verifyCodeAssistant.checkEmailVerifyCode(email, verifyCode);
        if (!verify) {
            throw CommonException.of(VERIFY_CODE_ERROR);
        }
        // 查找账号
        UaaAccountEntity account = accountService.findAccountByEmail(email);
        if (account == null) {
            throw CommonException.of(USER_NOT_FOUND);
        }
        // 取出账号
        String username = account.getUsername();
        Long userCode = account.getCode();
        // 登录
        return loginAssistant.buildLoginResult(userCode, username);
    }

    @Override
    public LoginResult loginByUsernameAndPassword(String username, String password) {
        // 查询用户
        UaaAccountEntity account = accountService.findAccountByUsername(username);
        if (account == null) {
            throw CommonException.of(USER_NOT_FOUND);
        }
        // 校验密码
        boolean match = loginAssistant.matches(password, account.getPassword());
        if (!match) {
            throw CommonException.of(PASSWORD_ERROR);
        }
        // 取出账号编码
        Long userCode = account.getCode();
        // 取出权限
        return loginAssistant.buildLoginResult(userCode, username);
    }

    @Override
    public boolean resetPasswordByMobile(String mobile, String verifyCode) {
        // 校验验证码
        boolean verify = verifyCodeAssistant.checkSmsVerifyCode(mobile, verifyCode);
        if (!verify) {
            throw CommonException.of(VERIFY_CODE_ERROR);
        }
        // 查找账号
        UaaAccountEntity account = accountService.findAccountByMobile(mobile);
        if (account == null) {
            throw CommonException.of(USER_NOT_FOUND);
        }
        accountService.resetPassword(account);
        return true;
    }

    @Override
    public boolean resetPasswordByEmail(String email, String verifyCode) {
        // 校验验证码
        boolean verify = verifyCodeAssistant.checkEmailVerifyCode(email, verifyCode);
        if (!verify) {
            throw CommonException.of(VERIFY_CODE_ERROR);
        }
        // 查找账号
        UaaAccountEntity account = accountService.findAccountByEmail(email);
        if (account == null) {
            throw CommonException.of(USER_NOT_FOUND);
        }
        accountService.resetPassword(account);
        return true;
    }

    @Override
    public LoginResult refreshLoginResult(String refreshToken) {
        // 去除前缀
        refreshToken = refreshToken.replace(HttpConstants.TOKEN_PREFIX, "");
        // 校验刷新令牌
        boolean verify = loginAssistant.validateToken(refreshToken);
        if (!verify) {
            throw CommonException.of(REFRESH_TOKEN_ERROR);
        }
        // 取出用户编码
        Long userCode = jwtAssist.getUserCodeFromToken(refreshToken);
        // 取出用户名
        String username = jwtAssist.getUserIdFromToken(refreshToken);
        // 构建登录结果
        return loginAssistant.buildLoginResult(userCode, username);
    }

    @Override
    public boolean activateAccount(String activateCode) {
        // 激活账号
        return accountService.activateAccount(activateCode);
    }

}
